package com.fdb.basic.framework.core.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fdb.basic.framework.core.exception.BizException;


public class DateUtility {
	private static Logger logger = LoggerFactory.getLogger(DateUtility.class);
    /**
     * 时间格式化
     */
    public final static String      TIME_FORMATE_MODE   = "yyyy-MM-dd HH:mm:ss";

	public static Date getCurrAppDate() {
		return new Date();
	}
	
	public static String getCurrAppDateStr() {
		return formatDate(getCurrAppDate(), "yyyy-MM-dd");
	}
	
	public static String formatDate(Date date, String pattern) {
		return new SimpleDateFormat(pattern).format(date);
	}
	
	public static String getCurrAppTimeStr() {
		return formatDate(getCurrAppDate(), "HH:mm:ss");
	}
	
	public static String getCurrAppDateTimeStr() {
		return formatDate(getCurrAppDate(), "yyyy-MM-dd HH:mm:ss");
	}
	
	/**
	 * 
	 * <p>
	 * <h2>简述</h2>
	 * 		<ol>获取当前时间格式为yyyy-MM-dd HH:mm:ss</ol>
	 * <h2>功能描述</h2>
	 * 		<ol>请添加功能详细的描述</ol>
	 * </p>
	 * @return
	 */
	public static String getCurrAppDateTimeString(){
	    return formatDate(getCurrAppDate(), "yyyy-MM-dd HH:mm:ss");
	}
	
	/**
	 * 
	 * <p>
	 * <h2>日期8转10</h2>
	 * 		<ol>请添加简述</ol>
	 * <h2>功能描述</h2>
	 * 		<ol>请添加功能详细的描述</ol>
	 * </p>
	 * @param date
	 * @return
	 */
	public static String format8To10(String date) {
		return DateUtility.formatDate(DateUtility.parseDate(date, "yyyyMMdd"), "yyyy-MM-dd");
	}
	
	/**
	 * 
	 * <p>
	 * <h2>日期10转10</h2>
	 * 		<ol>请添加简述</ol>
	 * <h2>功能描述</h2>
	 * 		<ol>请添加功能详细的描述</ol>
	 * </p>
	 * @param date
	 * @return
	 */
	public static String format10To10(String date) throws BizException {
		return DateUtility.formatDate(DateUtility.parseDate(date, "yyyy/MM/dd"), "yyyy-MM-dd");
	}
	
	/**
     * 
     * <p>
     * <h2>日期10转8</h2>
     *      <ol>请添加简述</ol>
     * <h2>功能描述</h2>
     *      <ol>请添加功能详细的描述</ol>
     * </p>
     * @param date
     * @return
     */
	public static String format10To8(String date) {
        return DateUtility.formatDate(DateUtility.parseDate(date, "yyyy-MM-dd"), "yyyyMMdd");
    }
	
	/**
	 * 
	 * <p>
	 * <h2>简述</h2>
	 * 		<ol>按照格式格式化日期字符串， 如格式化不成功返回当前应用日期</ol>
	 * <h2>功能描述</h2>
	 * 		<ol>请添加功能详细的描述</ol>
	 * </p>
	 * @param dateStr
	 * @param pattern
	 * @return
	 */
	public static Date parseDate(String dateStr, String pattern) {
		try {
			return new SimpleDateFormat(pattern).parse(dateStr);
		} catch (ParseException e) {
			
		}
		return DateUtility.getCurrAppDate();
	}
	
	/**
	 * 
	 * <p>
	 * <h2>简述</h2>
	 * 		<ol>根据格式化校验日期</ol>
	 * <h2>功能描述</h2>
	 * 		<ol>请添加功能详细的描述</ol>
	 * </p>
	 * @param date
	 * @param pattern
	 * @throws BizExceptipon
	 */
	public static void checkDate(String date, String pattern) throws BizException {
		try {
			new SimpleDateFormat(pattern).parse(date);
		} catch (ParseException e) {
			throw new BizException("日期"+ date +"不符合"+ pattern +"格式!");
		}
	}
	/**
     * 判断传递参数是否为日期类型、否则抛异常
     * 
     * @param dateStr
     * @param sName
     * @throws BizExceptipon
     *             date:2017-10-11 上午10:46:17 author:wangyk
     */
    public static void checkDate1(String dateStr, String sName) throws BizException {
        Pattern pattern = Pattern.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1][0-9])|([2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
        Matcher m = pattern.matcher(dateStr);
        if (m.matches()) {
            logger.info("传入参数【" + sName + "：" + dateStr + "】符合格式要求");
        } else {
            throw new BizException("传入参数【" + sName + "：" + dateStr + "】不符合格式要求");
        }
    }
	
    
    /**
     * @description:将日期格式为yyyy-MM-dd HH:mm:ss改为yyyyMMddHHmmss
     * @param date
     * @return
     * @throws BizException
     * @date:2018年12月17日 下午7:54:22
     * @author:wangyk3
     */
    public static String formatDateTime19To14(String date) throws BizException {
        if (date == null || "".equals(date)) {
            return "";
        }
        if (date.length() != 19) {
            throw new BizException("时间：" + date + "格式不合规");
        }
        try {
            SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sf2 = new SimpleDateFormat("yyyyMMddHHmmss");
            String dt = sf2.format(sf1.parse(date));
            return dt;
        } catch (Exception e) {
            throw new BizException("时间：" + date + "格式不合规");
        }
    }


    /**
     * @description:将日期格式为yyyy-MM-dd HH:mm:ss改为YYYYMMDDHHMMSS
     * @param date
     * @return
     * @throws BizException
     * @date:2020年01月22日
     * @author:dengqiwen
     */
    public static String formatDateTime19ToNew14(String date) throws BizException {
        if (date == null || "".equals(date)) {
            return "";
        }
        if (date.length() != 19) {
            throw new BizException("时间：" + date + "格式不合规");
        }
        try {
            SimpleDateFormat sf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sf2 = new SimpleDateFormat("YYYYMMDDHHMMSS");
            String dt = sf2.format(sf1.parse(date));
            return dt;
        } catch (Exception e) {
            throw new BizException("时间：" + date + "格式不合规");
        }
    }

    /**
     * @description:将日期格式为YYYYMMDDHHMMSS改为yyyy-MM-dd HH:mm:ss
     * @param date
     * @return
     * @throws BizException
     * @date:2018年12月17日 下午7:54:06
     * @author:wangyk3
     */
    public static String formatDateTime14To19(String date) throws BizException {
        if (date == null || "".equals(date)) {
            return "";
        }
        if (date.length() != 14) {
            throw new BizException("时间：" + date + "格式不合规");
        }
        try {
            SimpleDateFormat sfl = new SimpleDateFormat("yyyyMMddHHmmss");
            SimpleDateFormat sf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dt = sf2.format(sfl.parse(date));
            return dt;
        } catch (Exception e) {
            throw new BizException("时间：" + date + "格式不合规");
        }
    }
    
    /**
     * @description:将日期格式为yyyyMMddHHmmssSSS改为yyyy-MM-dd HH:mm:ss
     * @author  qiuyf
     * @since 2019年4月28日 下午4:16:16
     * @version 0.1 初始为0.1,后续变更则修改
     */
    public static String formatDateTime17To19(String date) throws BizException {
        if (date == null || "".equals(date)) {
            return "";
        }
        if (date.length() != 17) {
            throw new BizException("时间：" + date + "格式不合规");
        }
        try {
            SimpleDateFormat sfl = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            SimpleDateFormat sf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dt = sf2.format(sfl.parse(date));
            return dt;
        } catch (Exception e) {
            throw new BizException("时间：" + date + "格式不合规");
        }
    }
    
    
    /**
     * @description:返回当前年
     * @param dateStr
     * @return
     * @date:2018年12月17日 下午7:53:21
     * @author:wangyk3
     */
    public static int getCurrentYear(String dateStr) {
        String date[] = dateStr.split("-");
        return Integer.parseInt(date[0], 10);
    }

    /**
     * @description:返回当前月
     * @param dateStr
     * @return
     * @date:2018年12月17日 下午7:53:14
     * @author:wangyk3
     */
    public static int getCurrentMonth(String dateStr) {
        String date[] = dateStr.split("-");
        return Integer.parseInt(date[1], 10);
    }

    /**
     * @description:返回当前日
     * @param dateStr
     * @return
     * @date:2018年12月17日 下午7:52:01
     * @author:wangyk3
     */
    public static int getCurrentDay(String dateStr) {
        String date[] = dateStr.split("-");
        return Integer.parseInt(date[2], 10);
    }

    /**
     * @description:返回四位字符串
     * @param y
     * @return
     * @date:2018年12月17日 下午7:53:05
     * @author:wangyk3
     */
    public static String bYearZero(int y) {
        if (y < 10) {
            return "000" + String.valueOf(y);
        } else if (y < 100) {
            return "00" + String.valueOf(y);
        } else if (y < 1000) {
            return "0" + String.valueOf(y);
        }
        return String.valueOf(y);
    }

    /**
     * @description:返回两位字符串
     * @param m
     * @return
     * @date:2018年12月17日 下午7:51:24
     * @author:wangyk3
     */
    public static String bZero(int m) {
        return (m < 10 ? ("0" + String.valueOf(m)) : String.valueOf(m));
    }

    /**
     * @description:返回日期进过指定月数后的日期
     * @param dateStr
     * @param hkm
     * @return
     * @date:2018年12月17日 下午7:51:04
     * @author:wangyk3
     */
    public static String getDateStr(String dateStr, int hkm) {
        String reDateStr = "";
        int yy = Integer.parseInt(dateStr.substring(0, 4), 10);
        int mm = Integer.parseInt(dateStr.substring(4, 6), 10);
        int dd = Integer.parseInt(dateStr.substring(6, 8), 10);
        int yy2 = 0, mm2 = 0, dd2 = dd;
        if ((mm + hkm) % 12 == 0) {
            yy2 = yy + (mm + hkm) / 12 - 1;
            mm2 = 12;
        } else {
            if ((mm + hkm) % 12 == 1) {
                yy2 = yy + (mm + hkm) / 12;
                mm2 = 1;
            } else {
                yy2 = yy + (mm + hkm) / 12;
                mm2 = (mm + hkm) % 12;
            }
        }
        reDateStr = String.valueOf(yy2) + "-" + bZero(mm2) + "-" + bZero(dd2);
        return reDateStr;
    }

    /**
     * @description:返回月的天数
     * @param year
     * @param month
     * @return
     * @date:2018年12月17日 下午7:50:53
     * @author:wangyk3
     */
    public static int getMonthDays(int year, int month) {
        int days = 1;
        boolean isrn = (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? true : false;
        switch (month) {
        case 1:
            days = 31;
            break;
        case 2:
            if (isrn)
                days = 29;
            else
                days = 28;
            break;
        case 3:
            days = 31;
            break;
        case 4:
            days = 30;
            break;
        case 5:
            days = 31;
            break;
        case 6:
            days = 30;
            break;
        case 7:
            days = 31;
            break;
        case 8:
            days = 31;
            break;
        case 9:
            days = 30;
            break;
        case 10:
            days = 31;
            break;
        case 11:
            days = 30;
            break;
        case 12:
            days = 31;
        }
        return days;
    }

    /**
     * @description:返回两个日期之间的天数
     * @param beginDate
     * @param endDate
     * @return
     * @date:2018年12月17日 下午7:50:39
     * @author:wangyk3
     */
    public static int getBetweenDays(String beginDate, String endDate) {
        int sum = 0;
        int beginYear = getCurrentYear(beginDate);
        int beginMonth = getCurrentMonth(beginDate);
        int beginDay = getCurrentDay(beginDate);
        int endYear = getCurrentYear(endDate);
        int endMonth = getCurrentMonth(endDate);
        int endDay = getCurrentDay(endDate);
        String startDateStr = bYearZero(beginYear) + bZero(beginMonth) + "01";
        int sumMonth = (endYear - beginYear + 1) * 12 - (beginMonth) - (12 - endMonth);
        for (int i = 0; i < sumMonth; i++) {
            String dateStr = getDateStr(startDateStr, i);
            sum = sum + getMonthDays(getCurrentYear(dateStr), getCurrentMonth(dateStr));
        }
        sum = sum - beginDay + endDay;
        return sum;
    }
    /**
     * @description:获取当前日期，日期格式为YYYY-MM-DD
     * @return
     * @date:2018年12月17日 下午7:50:15
     * @author:wangyk3
     */
    public static String getCurrDate() {
        String TIME_FORMATE_MODE = "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMATE_MODE);
        return sdf.format(new Date());
    }

    /**
     * @description:获取当前时间，日期格式为YYYY-MM-DD HH:mm:ss
     * @return
     * @date:2018年12月17日 下午7:50:04
     * @author:wangyk3
     */
    public static String getCurrDateTime() {
        String TIME_FORMATE_MODE = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMATE_MODE);
        return sdf.format(new Date());
    }

    /**
     * 获取当前时间，格式为HH:mm:ss
     * 
     * @return data:2015-3-4下午03:30:29 author:chenw
     */
    public static String getCurrTime() {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        return df.format(new Date());
    }
    /**
     * @description:日期加天
     * @param optype
     * @param date
     * @param num
     * @return
     * @date:2018年12月17日 下午7:49:25
     * @author:wangyk3
     */
    private static String ADD_DATE(int optype, String date, int num) {
        String st_return = "";
        try {
            DateFormat daf_date = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.CHINA);
            daf_date.parse(date);
            Calendar calendar = daf_date.getCalendar();
            calendar.add(optype, num);
            String st_m = "";
            String st_d = "";
            int y = calendar.get(Calendar.YEAR);
            int m = calendar.get(Calendar.MONTH) + 1;
            int d = calendar.get(Calendar.DAY_OF_MONTH);
            if (m <= 9) {
                st_m = "0" + m;
            } else {
                st_m = "" + m;
            }
            if (d <= 9) {
                st_d = "0" + d;
            } else {
                st_d = "" + d;
            }
            st_return = y + "-" + st_m + "-" + st_d;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return st_return;
    }

    /**
     * 增加天数
     * 
     * @param date
     * @param n
     * @return
     */
    public static String ADD_DAY(String date, int n) {
        return DateUtility.ADD_DATE(Calendar.DATE, date, n);
    }

    /**
     * 增加月数
     * 
     * @param date
     * @param n
     * @return
     */
    public static String ADD_MONTH(String date, int n) {
        return DateUtility.ADD_DATE(Calendar.MONTH, date, n);
    }


    /**
     * @description:根据终止日和相隔月数计算起始日
     * @param endDate
     * @param months
     * @return
     * @throws BizException
     * @date:2018年12月17日 下午7:49:05
     * @author:wangyk3
     */
    public static String getStartDateByMonths(Date endDate, int months) throws BizException {
        String startDate = "";
        if (endDate == null) {
            return null;
        }
        try {
            Calendar calendarEndDate = Calendar.getInstance();
            calendarEndDate.setTime(endDate);
            calendarEndDate.add(Calendar.MONTH, 0 - months);
            SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
            startDate = sdf.format(calendarEndDate.getTime());
        } catch (Exception e) {
            throw new BizException("时间：" + endDate + "格式不合规");
        }
        return startDate;
    }

    /**
     * 根据终止日和相隔月数计算起始日
     * 
     * @param endDate
     *            结束日期
     * @param months
     *            相隔月数
     * @return String yyyy-MM
     * @author:maoyf
     * @date:2015-01-30上午10:41:29
     */
    public static String getStartMonthByMonths(Date endDate, int months) throws BizException {
        String startMonth = "";
        if (endDate == null) {
            return null;
        }
        try {
            Calendar calendarEndDate = Calendar.getInstance();
            calendarEndDate.setTime(endDate);
            calendarEndDate.add(Calendar.MONTH, 0 - months);
            SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM");
            startMonth = sdf.format(calendarEndDate.getTime());
        } catch (Exception e) {
            throw new BizException("时间：" + endDate + "格式不合规");
        }
        return startMonth;
    }
    
    /**
     * 
     * <p>
     * <h2>简述</h2>
     * 		<ol>日期格式转换将YYYY-MM-DD转换为YYYY/MM/DD</ol>
     * <h2>功能描述</h2>
     * 		<ol>请添加功能详细的描述</ol>
     * </p>
     * @param date
     * @return
     */
    public static String changeDateFormat(String date){
        date = date.replace("-", "/");
        return date;
    }
    
    /**
     * 
     * <p>
     * <h2>简述</h2>
     * 		<ol>比较日期大小</ol>
     * <h2>功能描述</h2>
     * 		<ol>请添加功能详细的描述</ol>
     * </p>
     * @param date1
     * @param date2
     * @return
     * @throws BizExceptipon 
     */
    public static int compareToDate(String date1, String date2) throws BizException {
    	String TIME_FORMATE_MODE = "yyyy-MM-dd";
        DateFormat df = new SimpleDateFormat(TIME_FORMATE_MODE);
        try {
            Date dt1 = df.parse(date1);
            Date dt2 = df.parse(date2);
            return dt1.compareTo(dt2);
        } catch (ParseException e) {
            throw new BizException(e.getMessage(),e);
        }

    }

    /**
     * 获取基准日期date的上一个月的开始日期和结束日期
     * @param date
     * @return LocalDate[0]:上一个月的开始日期，LocalDate[0]:上一个月的结束日期
     */
    public static LocalDate[] getLastMonthSEDate(LocalDate date){
        LocalDate[] month =new LocalDate[2];
        LocalDate localDate = date.minusMonths(1);

        month[0] = localDate.withDayOfMonth(1);
        //上一个月的天数
        int lengthOfMonth = localDate.lengthOfMonth();
        month[1] = localDate.withDayOfMonth(lengthOfMonth);

        return month;
    }
    
}
